package com.hitqz.robot.biz.flow.component.patrol;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hitqz.robot.api.business.entity.PatrolResultEntity;
import com.hitqz.robot.api.business.enums.ResultTypeEnum;
import com.hitqz.robot.api.business.model.dto.FlowContextDto;
import com.hitqz.robot.api.business.model.dto.FlowPatrolTicketsDto;
import com.hitqz.robot.api.common.entity.*;
import com.hitqz.robot.biz.service.*;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutorService;

@Slf4j
@LiteflowComponent(value = "UpdateResult", name = "[巡检]更新报表")
@AllArgsConstructor
public class UpdateResult extends NodeComponent {

    private final PatrolItemService patrolItemService;

    private final PatrolObjectService patrolObjectService;

    private final PatrolResultService patrolResultService;

    private final PatrolObjectStandardService patrolObjectStandardService;

    private final PatrolCheckTypeService patrolCheckTypeService;

    private final ExecutorService customThreadPool;

    @Override
    public void process() throws Exception {
        FlowContextDto dto = this.getRequestData();
        TicketsTask task = dto.getTicketsTask();
        log.info("任务数据 {}", task.getParseOrderParams());
        FlowPatrolTicketsDto params = JSONObject.parseObject(task.getParseOrderParams(), FlowPatrolTicketsDto.class);
        log.info("{} ---params: {}", task.getParseOrderParams(), JSONObject.toJSONString(params));
        if (params.getPatrolItemId() == null) {
            log.warn("没有检测项信息,不执行");
            return;
        }
        Integer patrolItemId = params.getPatrolItemId();
        PatrolItem item = patrolItemService.getById(patrolItemId);
        PatrolObject patrolObject = patrolObjectService.getById(item.getPatrolObjectId());
        PatrolCheckType checkType = patrolCheckTypeService.getById(patrolObject.getPatrolCheckTypeId());
        PatrolObjectStandard standard = patrolObjectStandardService.getOne(Wrappers.<PatrolObjectStandard>lambdaQuery().eq(PatrolObjectStandard::getPatrolObjectId, patrolObject.getId()).last("limit 1"));
        PatrolResultEntity patrolResult = patrolResultService.getOne(Wrappers.<PatrolResultEntity>lambdaQuery()
                .eq(PatrolResultEntity::getTicketsId, dto.getTickets().getId())
                //.eq(PatrolResult::getTicketsTaskId, dto.getTicketsTask().getId())
                .eq(PatrolResultEntity::getItemId, params.getPatrolItemId())
                .last("limit 1")
        );
        patrolResult.setCheckTime(new Date());
        //处理结果数据
        patrolResult.setVisionResult(params.getResult());
        patrolResult.setConvertValue(params.getResult());
        if (Objects.equals(patrolObject.getIsConvert(), 1) && StrUtil.isNotBlank(params.getResult())) {
            // 转换后的值,用来比较和做数据统计的
            // 0-无返回 1-浮点型 2-单个枚举 3-多个枚举 4-字符串  todo 前端加5-数显
            String resultType = checkType.getResultType();
            ResultTypeEnum resultTypeEnum = ResultTypeEnum.fromType(resultType);
            if (resultTypeEnum != null) {
                switch (resultTypeEnum) {
                    //todo 新增和编辑去检查有没有 ,
                    case FLOAT -> {
                        String[] convertValues = patrolObject.getFloatConvert().split(",");
                        BigDecimal convertMinValue = new BigDecimal(convertValues[0]);
                        BigDecimal convertMaxValue = new BigDecimal(convertValues[1]);
                        BigDecimal visionResult = new BigDecimal(params.getResult());
                        double convertValue = visionResult.multiply(convertMaxValue.subtract(convertMinValue)).add(convertMinValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
                        patrolResult.setConvertValue(String.valueOf(convertValue));
                    }
                    case SINGLE_ENUM, MULTI_ENUM -> {
                        //todo 新增和编辑去检查有没有 , 还有数量关系
                        String[] enumResults = patrolObject.getEnumResult().split(",");
                        String[] enumConverts = patrolObject.getEnumConvert().split(",");
                        for (int i = 0; i < enumResults.length; i++) {
                            if (Objects.equals(enumResults[i], params.getResult())) {
                                patrolResult.setConvertValue(enumConverts[i]);
                                break;
                            }
                        }
                    }
                    case LED -> {
                        //todo 前端要加
                        Integer afterPointCountConvert = patrolObject.getAfterPointCountConvert();
                        if (!params.getResult().contains(".") && Objects.equals(afterPointCountConvert,0)) {
                            BigDecimal value = new BigDecimal(params.getResult());
                            BigDecimal point = BigDecimal.valueOf(Math.pow(10, afterPointCountConvert));
                            double v = value.divide(point).setScale(afterPointCountConvert, RoundingMode.HALF_UP).doubleValue();
                            patrolResult.setConvertValue(String.valueOf(v));
                        }
                    }
                }
            }
        }
        // 对比结果
        // 0-未检测 1-正常 2-异常 3-视觉识别失败
        patrolResult.setStatus(1);
        String normalValue = Optional.ofNullable(standard).map(PatrolObjectStandard::getStandardValue).orElse("");
        if (Objects.equals(checkType.getIsVision(), 1) && StrUtil.isBlank(params.getResult())) {
            //视觉检测项但是没有结果，判定为失败
            patrolResult.setStatus(3);
        } else if (StrUtil.isNotBlank(normalValue) && StrUtil.isNotBlank(patrolResult.getConvertValue())) {
            switch (Optional.ofNullable(standard).map(PatrolObjectStandard::getType).orElse("-1")) {
                case "1" -> {
                    //值判定
                    patrolResult.setStatus(normalValue.contains(patrolResult.getConvertValue()) ? 1 : 2);
                }
                case "2" -> {
                    //区间判定 todo 新增和编辑去检查有没有 ,
                    String[] values = normalValue.split(",");
                    float minValue = Float.parseFloat(values[0]);
                    float maxValue = Float.parseFloat(values[1]);
                    float checkValue = Float.parseFloat(patrolResult.getConvertValue());
                    patrolResult.setStatus((minValue <= checkValue && checkValue <= maxValue) ? 1 : 2);
                }
            }
        }
        // 标准值
        patrolResult.setNormalValue(normalValue);
        // 展示在报表的值 转换后的值+单位
        patrolResult.setShowValue(Optional.ofNullable(patrolResult.getConvertValue()).orElse("") + " " + patrolObject.getUnit());
        patrolResult.setMediaUrl(params.getMediaUrl());
        patrolResult.setVisionMediaUrl(params.getVisionUrl());
        patrolResultService.saveOrUpdate(patrolResult);
        // 上传到服务端

        // todo 报警

        Runnable runnableTask = () -> {
            //todo 上传到服务端 0-未上传 1-已上传 2-上传失败
            patrolResult.setUploadStatus(0);
            patrolResultService.saveOrUpdate(patrolResult);
        };
        customThreadPool.submit(runnableTask);
    }

}